home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / guile-ii.src / guile-ii / guile-src / gls / Ginit.scm < prev    next >
Encoding:
Text File  |  1995-08-17  |  35.6 KB  |  1,302 lines

  1. ;;;;     copyright (C) 1995 Free Software Foundation, Inc.
  2. ;;;; 
  3. ;;;; This program is free software; you can redistribute it and/or modify
  4. ;;;; it under the terms of the GNU General Public License as published by
  5. ;;;; the Free Software Foundation; either version 2, or (at your option)
  6. ;;;; any later version.
  7. ;;;; 
  8. ;;;; This program is distributed in the hope that it will be useful,
  9. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. ;;;; GNU General Public License for more details.
  12. ;;;; 
  13. ;;;; You should have received a copy of the GNU General Public License
  14. ;;;; along with this software; see the file COPYING.  If not, write to
  15. ;;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ;;;; 
  17.  
  18.  
  19. ;;; Parts of this file derived from
  20. ;;;     "Init.scm", Scheme initialization code for SCM.
  21. ;;;     Copyright (C) 1991, 1992, 1993, 1994 Aubrey Jaffer.
  22. ;;;
  23.  
  24. (define (scheme-implementation-type) 'GUILE)
  25. (define (scheme-implementation-version) 'iii)
  26.  
  27.  
  28. (define < <?)
  29. (define <= <=?)
  30. (define = =?)
  31. (define > >?)
  32. (define >= >=?)
  33.  
  34.  
  35.  
  36. ;;; {Features}
  37. ;;;
  38. ;;; Features are named options which may or may not be present
  39. ;;; in an interpreter.  They can be tested for either by code or
  40. ;;; by conditional forms (e.g. "#- hash (load-slib-hash)" )
  41. ;;;
  42.  
  43. (set! *features*
  44.       (append '(getenv tmpnam abort transcript with-file
  45.         ieee-p1178 rev4-report rev4-optional-procedures
  46.         hash hash-table object-hash delay eval dynamic-wind
  47.         multiarg-apply multiarg/and- logical defmacro
  48.         string-port source current-time)
  49.           *features*))
  50.  
  51.  
  52. ;; Evaluate a boolean expression whose terms are feature names.
  53. ;;
  54. (define (read:eval-feature exp)
  55.   (cond ((symbol? exp)
  56.      (or (memq exp *features*) (eq? exp (software-type))))
  57.     ((and (pair? exp) (list? exp))
  58.      (case (car exp)
  59.        ((not) (not (read:eval-feature (cadr exp))))
  60.        ((or) (if (null? (cdr exp)) #f
  61.              (or (read:eval-feature (cadr exp))
  62.              (read:eval-feature (cons 'or (cddr exp))))))
  63.        ((and) (if (null? (cdr exp)) #t
  64.               (and (read:eval-feature (cadr exp))
  65.                (read:eval-feature (cons 'and (cddr exp))))))
  66.        (else (error "read:sharp+ invalid expression " exp))))))
  67.  
  68.  
  69. ;;; {Reader Extensions}
  70. ;;;
  71. ;;; Reader code for various "#c" forms.
  72. ;;;
  73.  
  74.   
  75. (define (read:sharp c port)
  76.   (define (barf)
  77.     (error "unknown # object" c))
  78.   (case c ((#\') (read port))
  79.     ((#\+) (if (read:eval-feature (read port))
  80.            (read port)
  81.            (begin (read port) (if #f #f))))
  82.     ((#\-) (if (not (read:eval-feature (read port)))
  83.            (read port)
  84.            (begin (read port) (if #f #f))))
  85.     ((#\b) (read:uniform-vector #t port))
  86.     ((#\a) (read:uniform-vector #\a port))
  87.     ((#\u) (read:uniform-vector 1 port))
  88.     ((#\e) (read:uniform-vector -1 port))
  89.     ((#\s) (read:uniform-vector 1.0 port))
  90.     ((#\i) (read:uniform-vector 1/3 port))
  91.     ((#\c) (read:uniform-vector 0+i port))
  92.     ((#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)
  93.      (read:array c port))
  94.     ((#\!) (if (= 1 (line-number))
  95.            (let skip () (if (eq? #\newline (peek-char port))
  96.                     (if #f #f)
  97.                     (begin (read-char port) (skip))))
  98.            (barf)))
  99.     (else (barf))))
  100.  
  101. (define (read:array digit port)
  102.   (define chr0 (char->integer #\0))
  103.   (let ((rank (let readnum ((val (- (char->integer digit) chr0)))
  104.         (if (char-numeric? (peek-char port))
  105.             (readnum (+ (* 10 val)
  106.                 (- (char->integer (read-char port)) chr0)))
  107.             val)))
  108.     (prot (if (eq? #\( (peek-char port))
  109.           '()
  110.           (let ((c (read-char port)))
  111.             (case c ((#\b) #t)
  112.               ((#\a) #\a)
  113.               ((#\u) 1)
  114.               ((#\e) -1)
  115.               ((#\s) 1.0)
  116.               ((#\i) 1/3)
  117.               ((#\c) 0+i)
  118.               (else (error "read:array unknown option " c)))))))
  119.     (if (eq? (peek-char port) #\()
  120.     (list->uniform-array rank prot (read port))
  121.     (error "read:array list not found"))))
  122.  
  123. (define (read:uniform-vector proto port)
  124.   (if (eq? #\( (peek-char port))
  125.       (list->uniform-array 1 proto (read port))
  126.       (error "read:uniform-vector list not found")))
  127.  
  128.  
  129. ;;; {Here are Some Revised^2 Scheme Functions}
  130. ;;;
  131.  
  132. (define 1+
  133.   (let ((+ +))
  134.     (lambda (n) (+ n 1))))
  135.  
  136. (define -1+
  137.   (let ((+ +))
  138.     (lambda (n) (+ n -1))))
  139.  
  140.  
  141. (define 1- -1+)
  142. (define t #t)
  143. (define nil #f)
  144. (define sequence begin)
  145.  
  146. (set! apply (lambda (fun . args) (@apply fun (apply:nconc2last args))))
  147.  
  148. (define (call-with-current-continuation proc)
  149.   (@call-with-current-continuation proc))
  150.  
  151.  
  152.  
  153. ;;; {Slib-ish Names for Bit-twiddling Functions}
  154. ;;;
  155.  
  156. (define logical:logand logand)
  157. (define logical:logior logior)
  158. (define logical:logxor logxor)
  159. (define logical:lognot lognot)
  160. (define logical:ash ash)
  161. (define logical:logcount logcount)
  162. (define logical:integer-length integer-length)
  163. (define logical:bit-extract bit-extract)
  164. (define logical:integer-expt integer-expt)
  165.  
  166. (define (logical:ipow-by-squaring x k acc proc)
  167.   (cond ((zero? k) acc)
  168.     ((= 1 k) (proc acc x))
  169.     (else (logical:ipow-by-squaring (proc x x)
  170.                     (quotient k 2)
  171.                     (if (even? k) acc (proc acc x))
  172.                     proc))))
  173.  
  174.  
  175.  
  176. ;;; {Basic Port Code}
  177. ;;; 
  178. ;;; Specificly, the parts of the low-level port code that are written in 
  179. ;;; Scheme rather than C.
  180. ;;;
  181.  
  182. ;; VMS does something strange when output is sent to both
  183. ;; CURRENT-OUTPUT-PORT and CURRENT-ERROR-PORT.
  184. (case (software-type)
  185.   ((VMS) (set-current-error-port (current-output-port))))
  186.  
  187. ;; OPEN_READ, OPEN_WRITE, and OPEN_BOTH are used to request the proper
  188. ;; mode to open files in.  MSDOS does carraige return - newline
  189. ;; translation if not opened in `b' mode.
  190. ;;
  191. (define OPEN_READ (case (software-type)
  192.             ((MS-DOS WINDOWS ATARIST) "rb")
  193.             (else "r")))
  194. (define OPEN_WRITE (case (software-type)
  195.              ((MS-DOS WINDOWS ATARIST) "wb")
  196.              (else "w")))
  197. (define OPEN_BOTH (case (software-type)
  198.             ((MS-DOS WINDOWS ATARIST) "r+b")
  199.             (else "r+")))
  200.  
  201.  
  202. (define (open-input-file str)
  203.   (or (open-file str OPEN_READ)
  204.       (error "OPEN-INPUT-FILE couldn't find file " str)))
  205.  
  206. (define (open-output-file str)
  207.   (or (open-file str OPEN_WRITE)
  208.       (error "OPEN-OUTPUT-FILE couldn't find file " str)))
  209.  
  210. (define (open-io-file str) (open-file str OPEN_BOTH))
  211. (define close-input-port close-port)
  212. (define close-output-port close-port)
  213. (define close-io-port close-port)
  214.  
  215. (define (call-with-input-file str proc)
  216.   (let* ((file (open-input-file str))
  217.      (ans (proc file)))
  218.     (close-input-port file)
  219.     ans))
  220.  
  221. (define (call-with-output-file str proc)
  222.   (let* ((file (open-output-file str))
  223.      (ans (proc file)))
  224.     (close-output-port file)
  225.     ans))
  226.  
  227. (define (with-input-from-port port thunk)
  228.   (let* ((swaports (lambda () (set! port (set-current-input-port port)))))
  229.     (dynamic-wind swaports thunk swaports)))
  230.  
  231. (define (with-output-to-port port thunk)
  232.   (let* ((swaports (lambda () (set! port (set-current-output-port port)))))
  233.     (dynamic-wind swaports thunk swaports)))
  234.  
  235. (define (with-error-to-port port thunk)
  236.   (let* ((swaports (lambda () (set! port (set-current-error-port port)))))
  237.     (dynamic-wind swaports thunk swaports)))
  238.  
  239. (define (with-input-from-file file thunk)
  240.   (let* ((nport (open-input-file file))
  241.      (ans (with-input-from-port nport thunk)))
  242.     (close-port nport)
  243.     ans))
  244.  
  245. (define (with-output-to-file file thunk)
  246.   (let* ((nport (open-output-file file))
  247.      (ans (with-output-to-port nport thunk)))
  248.     (close-port nport)
  249.     ans))
  250.  
  251. (define (with-error-to-file file thunk)
  252.   (let* ((nport (open-output-file file))
  253.      (ans (with-error-to-port nport thunk)))
  254.     (close-port nport)
  255.     ans))
  256.  
  257.  
  258. (if (not (defined? output-port-width))
  259.     (define (output-port-width . arg) 80))
  260.  
  261. (if (not (defined? output-port-height))
  262.     (define (output-port-height . arg) 24))
  263.  
  264. (define (with-input-from-string string thunk)
  265.   (call-with-input-string string
  266.    (lambda (p) (with-input-from-port p thunk))))
  267.  
  268. (define (with-output-to-string thunk)
  269.   (call-with-input-string
  270.    (lambda (p) (with-output-to-port p thunk))))
  271.  
  272. (define (with-error-to-string thunk)
  273.   (call-with-input-string
  274.    (lambda (p) (with-error-to-port p thunk))))
  275.  
  276.  
  277.  
  278. ;;; {Symbol Properties}
  279. ;;;
  280.  
  281. (define (symbol-property sym prop)
  282.   (let ((pair (assoc prop (symbol-pref sym))))
  283.     (and pair (cdr pair))))
  284.  
  285. (define (set-symbol-property! sym prop val)
  286.   (let ((pair (assoc prop (symbol-pref sym))))
  287.     (if pair
  288.     (set-cdr! pair val)
  289.     (symbol-pset! sym (acons prop val (symbol-pref sym))))))
  290.  
  291. (define (set-symbol-property! sym prop val)
  292.   (let ((pair (assoc prop (symbol-pref sym))))
  293.     (if pair
  294.     (set-cdr! pair val)
  295.     (symbol-pset! sym (acons prop val (symbol-pref sym))))))
  296.  
  297. (define (symbol-property-remove! sym prop)
  298.   (let ((pair (assoc prop (symbol-pref sym))))
  299.     (if pair
  300.     (symbol-pset! sym (delq! pair (symbol-pref sym))))))
  301.  
  302.  
  303. ;;; {Error Handling}
  304. ;;;
  305.  
  306.  
  307. ;; %%bad-throw is the hook that is called upon a throw to a an unhandled
  308. ;; key.  If the key has a default handler (a throw-handler-default property),
  309. ;; it is applied to the throw.
  310. ;;
  311. (define (%%bad-throw key . args)
  312.   (let ((default (and (symbol? key)
  313.               (symbol-property key 'throw-handler-default))))
  314.     (and default (apply default key args))))
  315.  
  316. ;; (error . args) is short for (throw (quote error) . args)
  317. ;;
  318. (define (error . args)
  319.   (apply throw 'error args))
  320.  
  321. ;; Error handling a la SCM.
  322. ;;
  323. (define (%%default-error-handler ignored . args)
  324.   (define cep (current-error-port))
  325.   (perror "ERROR")
  326.   (errno 0)
  327.   (display "ERROR: " cep)
  328.   (if (not (null? args))
  329.       (begin (display (car args) cep)
  330.          (for-each (lambda (x) (display #\  cep) (write x cep))
  331.                (cdr args))))
  332.   (newline cep)
  333.   (force-output cep)
  334.   (abort))
  335.  
  336.  
  337. ;; Install SCM error handling as the default.
  338. ;;
  339. (set-symbol-property! 'error
  340.               'throw-handler-default
  341.               %%default-error-handler)
  342.  
  343. ;; A number of internally defined error types are represented
  344. ;; as integers.  Here is the mapping to symbolic names
  345. ;; and error messages.
  346. ;;
  347. (define %%system-errors
  348.   '((-1 UNKNOWN "Unknown error")
  349.     (0 ARGn  "Wrong type argument to ")
  350.     (1 ARG1  "Wrong type argument in position 1 to ")
  351.     (2 ARG2  "Wrong type argument in position 2 to ")
  352.     (3 ARG3  "Wrong type argument in position 3 to ")
  353.     (4 ARG4  "Wrong type argument in position 4 to ")
  354.     (5 ARG5  "Wrong type argument in position 5 to ")
  355.     (6 ARG5  "Wrong type argument in position 5 to ")
  356.     (7 ARG5  "Wrong type argument in position 5 to ")
  357.     (8 WNA "Wrong number of arguments to ")
  358.     (9 OVFLOW "Numerical overflow to ")
  359.     (10 OUTOFRANGE "Argument out of range to ")
  360.     (11 NALLOC "Could not allocate to ")
  361.     (12 EXIT "Exit (internal error?).")
  362.     (13 HUP_SIGNAL "hang-up")
  363.     (14 INT_SIGNAL "user interrupt")
  364.     (15 FPE_SIGNAL "arithmetic error")
  365.     (16 BUS_SIGNAL "bus error")
  366.     (17 SEGV_SIGNAL "segmentation violation")
  367.     (18 ALRM_SIGNAL "alarm")))
  368.  
  369. ;; The default handler for built-in error types when
  370. ;; thrown by their symbolic name.
  371. ;;
  372. (define (%%handle-system-error ignored desc proc . args)
  373.   (let* ((b (assoc desc %%system-errors))
  374.      (msghead (cond
  375.            (b (caddr b))
  376.            ((or (symbol? desc) (string? desc))
  377.             (string-append desc " "))
  378.            (#t "Unknown error")))
  379.      (msg (if (symbol? proc)
  380.           (string-append msghead proc ":")
  381.           msghead))
  382.      (rest (if (and proc (not (symbol? proc)))
  383.            (cons proc args)
  384.            args))
  385.      (fixed-args (cons msg rest)))
  386.     (apply error fixed-args)))
  387.  
  388. ;; Install default handlers for built-in errors.
  389. ;;
  390. (map (lambda (err)
  391.        (set-symbol-property! (cadr err)
  392.                  'throw-handler-default
  393.                  %%handle-system-error))
  394.      (cdr %%system-errors))
  395.  
  396.  
  397. ;; All system errors are thrown as %%system-error.  Here
  398. ;; is the default handler that rethrows a more specific 
  399. ;; error.
  400. ;;
  401. (define (%%generic-system-error-handler ignored desc . args)
  402.   (let ((key (assoc desc %%system-errors)))
  403.     (if key
  404.     (apply throw (cadr key) desc args)
  405.     (apply throw 'UNKNOWN desc args))))
  406.  
  407. (set-symbol-property! '%%system-error
  408.               'throw-handler-default
  409.               %%handle-system-error)
  410.  
  411.  
  412.  
  413.  
  414.  
  415. ;;; {Misc.}
  416. ;;;
  417.  
  418. (define slib:exit quit)
  419. (define exit quit)
  420.  
  421.  
  422. (define (terms)
  423.   (list-file (in-vicinity (implementation-vicinity) "COPYING")))
  424.  
  425. (define (list-file file)
  426.   (call-with-input-file file
  427.     (lambda (inport)
  428.       (do ((c (read-char inport) (read-char inport)))
  429.       ((eof-object? c))
  430.     (write-char c)))))
  431.  
  432. (define (file-exists? str)
  433.   (let ((port (open-file str OPEN_READ)))
  434.     (if port (begin (close-port port) #t)
  435.     #f)))
  436.  
  437. (define set-errno errno)
  438.  
  439.  
  440. (define difftime -)
  441. (define offset-time +)
  442.  
  443. (if (not (memq 'ed *features*))
  444.     (begin
  445.       (define (ed . args)
  446.     (system (apply string-append
  447.                (or (getenv "EDITOR") "ed")
  448.                (map (lambda (s) (string-append " " s)) args))))
  449.       (set! *features* (cons 'ed *features*))))
  450.  
  451. (define (has-suffix? str suffix)
  452.   (let ((sufl (string-length suffix))
  453.     (sl (string-length str)))
  454.     (and (> sl sufl)
  455.      (string=? (substring str (- sl sufl) sl) suffix))))
  456.  
  457.  
  458. (define slib:error error)
  459. (define slib:tab #\tab)
  460. (define slib:form-feed #\page)
  461. (define slib:eval eval)
  462.  
  463.  
  464. ;;; {List Comparison}
  465. ;;;
  466.  
  467. ;; Compare two lists, describing insertions/deletions needed
  468. ;; to change one to the other.
  469. ;;
  470. (define (diff-lists a b cmp?)
  471.   (let* ((a-len (length a))
  472.      (b-len (length b))
  473.      (memo (make-array #f (+ a-len 1) (+ 1 b-len)))
  474.      (cost (compute-cost! a a-len b b-len memo cmp?))
  475.      (cost-at (lambda (x y) (array-ref memo x y))))
  476.     (letrec ((findpath (lambda (aa a-pos bb b-pos)
  477.              (cond
  478.               ((eq? a-pos 0) (map (lambda (e) `(+ ,e)) bb))
  479.               ((eq? b-pos 0) (map (lambda (e) `(- ,e)) aa))
  480.               ((cmp? (car aa) (car bb))
  481.                `((.. ,(car aa))
  482.                  ,@(findpath (cdr aa) (+ -1 a-pos)
  483.                      (cdr bb) (+ -1 b-pos))))
  484.               ((eq? (+ -1 (cost-at a-pos b-pos))
  485.                 (cost-at (+ -1 a-pos) b-pos))
  486.                `((- ,(car aa))
  487.                  ,@(findpath (cdr aa) (+ -1 a-pos) bb b-pos)))
  488.               (else
  489.                `((+ ,(car bb))
  490.                  ,@(findpath aa a-pos (cdr bb) (+ -1 b-pos))))))))
  491.       (findpath a a-len b b-len))))
  492.  
  493.  
  494. ;; Compute the number of insertions/deletions needed to change
  495. ;; one list into another.  The memo is a 2d array of at least 
  496. ;; a-len X b-len elements.  The memo is used to speed up computing
  497. ;; the cost, but really the side effects on the array are interesting
  498. ;; output.  Tracing the table later is how a specific sequence
  499. ;; of ins/del is computed.
  500. ;;
  501.  
  502. (define (compute-cost! a a-len b b-len memo cmp?)
  503.   (let ((answer
  504.      (cond
  505.       ((eq? 0 b-len) a-len)
  506.  
  507.       ((eq? 0 a-len) b-len)
  508.  
  509.       ((array-ref memo a-len b-len)
  510.        (array-ref memo a-len b-len))
  511.  
  512.       ((cmp? (car a) (car b))
  513.        (compute-cost! (cdr a) (+ -1 a-len)
  514.               (cdr b) (+ -1 b-len)
  515.               memo cmp?))
  516.  
  517.       (else
  518.        (let ((first-way (compute-cost! (cdr a) (+ -1 a-len)
  519.                        b b-len
  520.                        memo cmp?))
  521.          (second-way (compute-cost! a a-len
  522.                         (cdr b) (+ -1 b-len)
  523.                         memo cmp?)))
  524.          (+ 1 (min first-way second-way)))))))
  525.  
  526.     (array-set! memo answer a-len b-len)
  527.     answer))
  528.  
  529.  
  530.  
  531. ;;; {File Systems}
  532. ;;;
  533.  
  534.  
  535.  
  536. ;;; {Load}
  537. ;;;
  538.  
  539. (define load:indent 0)
  540.  
  541. (define (scm:load file . libs)
  542.   (define sfs (scheme-file-suffix))
  543.   (define cep (current-error-port))
  544.   (cond ((> (verbose) 1)
  545.       (display
  546.        (string-append ";" (make-string load:indent #\ ) "loading " file)
  547.        cep)
  548.       (set! load:indent (modulo (+ 2 load:indent) 16))
  549.       (newline cep)))
  550.   (force-output cep)
  551.   (let ((floaded
  552.      (or (and (defined? link:link) (not hss)
  553.           (or (and (apply link:link file libs) file)
  554.               (and link:able-suffix
  555.                (let ((fs (string-append file link:able-suffix)))
  556.                  (cond ((not (file-exists? fs)) #f)
  557.                    ((apply link:link fs libs) fs)
  558.                    (else #f))))))
  559.          (and (try-load file) file)
  560.          (let ((fs (string-append file sfs)))
  561.            (and (try-load fs) fs))
  562.          (let ((fs (in-vicinity (library-vicinity) file)))
  563.            (and (try-load fs) fs))
  564.          (let ((fs (string-append (in-vicinity (library-vicinity) file) sfs)))
  565.            (and (try-load fs) fs))
  566.          (begin
  567.            (set! load:indent 0)
  568.            (error "LOAD couldn't find file " file)))))
  569.     (errno 0)
  570.     (cond ((> (verbose) 1)
  571.        (set! load:indent (modulo (+ -2 load:indent) 16))
  572.        (display (string-append ";" (make-string load:indent #\ )
  573.                    "done loading " floaded)
  574.             cep)
  575.        (newline cep)
  576.        (force-output cep)))))
  577.  
  578. (define (scm:load-source file)
  579.   (define sfs (scheme-file-suffix))
  580.   (define cep (current-error-port))
  581.   (cond ((> (verbose) 1)
  582.      (display ";loading " cep) (write file cep) (newline cep)))
  583.   (force-output cep)
  584.   (let ((name-loaded
  585.      (or  (try-load file)
  586.           (let ((fs (string-append file sfs)))
  587.         (and (try-load fs) fs))
  588.           (let ((fs (in-vicinity (library-vicinity) file)))
  589.         (and (try-load fs) fs))
  590.           (let ((fs (string-append (in-vicinity (library-vicinity) file) sfs)))
  591.         (and (try-load fs) fs))
  592.           (error "LOAD couldn't find file " file))))
  593.     (errno 0)
  594.     (cond ((> (verbose) 1)
  595.        (display ";done loading " cep) (write name-loaded cep) (newline cep)
  596.        (force-output cep)))))
  597.  
  598.  
  599. ;; library-vicinity should return the pathname of the
  600. ;; directory where files of Scheme library functions reside.
  601. ;;
  602. (define library-vicinity
  603.   (let ((library-path
  604.      (or (getenv "SCHEME_LIBRARY_PATH")
  605.          (case (software-type)
  606.            ((UNIX COHERENT) (or (and (defined? compiled-library-path)
  607.                      (compiled-library-path))
  608.                     "/usr/local/lib/slib/"))
  609.            ((VMS) "lib$scheme:")
  610.            ((MS-DOS WINDOWS ATARIST) "C:\\SCM\\SLIB\\")
  611.            ((OS/2) "\\languages\\scm\\slib\\")
  612.            ((MACOS THINKC) "camus Napoleon:Think C4.0:scm3.0:")
  613.            ((AMIGA) "Scheme:libs/")
  614.            (else "")))))
  615.  
  616.     (lambda () library-path)))
  617.  
  618. ;; program-vicinity is here in case the Scheme Library cannot be found.
  619. ;;
  620.  
  621. (define program-vicinity
  622.   (let ((*vicinity-suffix*
  623.      (case (software-type)
  624.        ((UNIX COHERENT) '(#\/))
  625.        ((AMIGA) '(#\: #\/))
  626.        ((VMS) '(#\: #\]))
  627.        ((MS-DOS WINDOWS ATARIST OS/2) '(#\\))
  628.        ((MACOS THINKC) '(#\:)))))
  629.     (lambda ()
  630.       (let loop ((i (- (string-length *load-pathname*) 1)))
  631.     (cond ((negative? i) "")
  632.           ((memv (string-ref *load-pathname* i)
  633.              *vicinity-suffix*)
  634.            (substring *load-pathname* 0 (+ i 1)))
  635.           (else (loop (- i 1))))))))
  636.  
  637. ;;; Here for backward compatability
  638. ;;
  639. (define scheme-file-suffix
  640.   (case (software-type)
  641.     ((NOSVE) (lambda () "_scm"))
  642.     (else (lambda () ".scm"))))
  643.  
  644. (define in-vicinity string-append)
  645.  
  646. ;;; This is the vicinity where this file resides.
  647. (define implementation-vicinity
  648.   (let ((vic (program-vicinity)))
  649.     (lambda () vic)))
  650.  
  651.  
  652. (define load scm:load)
  653. (define slib:load load)
  654. (define slib:load-source scm:load-source)
  655.  
  656. (cond ((try-load
  657.     (in-vicinity (library-vicinity) "require" (scheme-file-suffix))))
  658.       (else
  659.        (perror "WARNING")
  660.        (display "WARNING: Couldn't find require.scm in (library-vicinity)"
  661.         (current-error-port))
  662.        (write (library-vicinity) (current-error-port))
  663.        (newline (current-error-port))
  664.        (errno 0)))
  665.  
  666.  
  667. ;;; DO NOT MOVE!  This has to be done after "require.scm" is loaded.
  668. (define slib:load-source scm:load-source)
  669. (define slib:load scm:load)
  670.  
  671.  
  672.  
  673. ;;; {Autoloads for SLIB Procedures}
  674. ;;;
  675.  
  676. (define (tracef . args) (require 'trace) (apply tracef args))
  677. (define (trace:tracef . args) (require 'trace) (apply trace:tracef args))
  678. (define (pretty-print . args) (require 'pretty-print)
  679.   (apply pretty-print args))
  680. (define (pp . args) (apply pretty-print args))
  681. (define (pk key val) (pp (list key val)) val)
  682. (define (print . args) (require 'debug) (apply print args))
  683.  
  684.  
  685.  
  686. (define (predicate->hash pred)
  687.   (cond ((eq? pred eq?) hashq)
  688.     ((eq? pred eqv?) hashv)
  689.     ((eq? pred equal?) hash)
  690.     ((eq? pred =) hashv)
  691.     ((eq? pred char=?) hashv)
  692.     ((eq? pred char-ci=?) hashv)
  693.     ((eq? pred string=?) hash)
  694.     ((eq? pred string-ci=?) hash)
  695.     (else (slib:error "unknown predicate for hash" pred))))
  696.  
  697. (define (make-hash-table k) (make-vector k '()))
  698.  
  699. (define (predicate->hash-asso pred)
  700.   (let ((hashfun (predicate->hash pred))
  701.     (asso (predicate->asso pred)))
  702.     (lambda (key hashtab)
  703.       (asso key
  704.         (vector-ref hashtab (hashfun key (vector-length hashtab)))))))
  705.  
  706. (define (hash-inquirer pred)
  707.   (let ((hashfun (predicate->hash pred))
  708.     (ainq (alist-inquirer pred)))
  709.     (lambda (hashtab key)
  710.       (ainq (vector-ref hashtab (hashfun key (vector-length hashtab)))
  711.         key))))
  712.  
  713. (define (hash-associator pred)
  714.   (let ((hashfun (predicate->hash pred))
  715.     (asso (alist-associator pred)))
  716.     (lambda (hashtab key val)
  717.       (let* ((num (hashfun key (vector-length hashtab))))
  718.     (vector-set! hashtab num
  719.              (asso (vector-ref hashtab num) key val)))
  720.       hashtab)))
  721.  
  722. (define (hash-remover pred)
  723.   (let ((hashfun (predicate->hash pred))
  724.     (arem (alist-remover pred)))
  725.     (lambda (hashtab key)
  726.       (let* ((num (hashfun key (vector-length hashtab))))
  727.     (vector-set! hashtab num
  728.              (arem (vector-ref hashtab num) key)))
  729.       hashtab)))
  730.  
  731. (define (hash-map proc ht)
  732.   (define nht (make-vector (vector-length ht)))
  733.   (do ((i (+ -1 (vector-length ht)) (+ -1 i)))
  734.       ((negative? i) nht)
  735.     (vector-set!
  736.      nht i
  737.      (alist-map proc (vector-ref ht i)))))
  738.  
  739. (define (hash-for-each proc ht)
  740.   (do ((i (+ -1 (vector-length ht)) (+ -1 i)))
  741.       ((negative? i))
  742.     (alist-for-each proc (vector-ref ht i))))
  743.  
  744.  
  745.  
  746. (define (predicate->asso pred)
  747.   (cond ((eq? eq? pred) assq)
  748.     ((eq? = pred) assv)
  749.     ((eq? eqv? pred) assv)
  750.     ((eq? char=? pred) assv)
  751.     ((eq? equal? pred) assoc)
  752.     ((eq? string=? pred) assoc)
  753.     (else (lambda (key alist)
  754.         (let l ((al alist))
  755.           (cond ((null? al) #f)
  756.             ((pred key (caar al)) (car al))
  757.             (else (l (cdr al)))))))))
  758.  
  759. (define (alist-inquirer pred)
  760.   (let ((assofun (predicate->asso pred)))
  761.     (lambda (alist key)
  762.       (let ((pair (assofun key alist)))
  763.     (and pair (cdr pair))))))
  764.  
  765. (define (alist-associator pred)
  766.   (let ((assofun (predicate->asso pred)))
  767.     (lambda (alist key val)
  768.       (let* ((pair (assofun key alist)))
  769.     (cond (pair (set-cdr! pair val)
  770.             alist)
  771.           (else (cons (cons key val) alist)))))))
  772.  
  773. (define (alist-remover pred)
  774.   (lambda (alist key)
  775.     (cond ((null? alist) alist)
  776.       ((pred key (caar alist)) (cdr alist))
  777.       ((null? (cdr alist)) alist)
  778.       ((pred key (caadr alist))
  779.        (set-cdr! alist (cddr alist)) alist)
  780.       (else
  781.        (let l ((al (cdr alist)))
  782.          (cond ((null? (cdr al)) alist)
  783.            ((pred key (caadr al))
  784.             (set-cdr! al (cddr al)) alist)
  785.            (else (l (cdr al)))))))))
  786.  
  787. (define (alist-map proc alist)
  788.   (map (lambda (pair) (cons (car pair) (proc (car pair) (cdr pair))))
  789.        alist))
  790.  
  791. (define (alist-for-each proc alist)
  792.   (for-each (lambda (pair) (proc (car pair) (cdr pair))) alist))
  793.  
  794.  
  795. ;;; {Dynamic Loading}
  796. ;;;
  797.  
  798. (if (or (defined? dld:link)
  799.     (defined? shl:load)
  800.     (defined? vms:dynamic-link-call)
  801.     (file-exists? (in-vicinity (implementation-vicinity) "hobbit.tms")))
  802.     (try-load (in-vicinity (implementation-vicinity)
  803.                "Link" (scheme-file-suffix))))
  804.  
  805. (cond ((defined? link:link)
  806.        (define slib:load-compiled link:link)
  807.        (provide 'compiled)))
  808.  
  809. ;;; {Macros}
  810. ;;;
  811.  
  812. ;defmacro from dorai@cs.rice.edu (heavily hacked by jaffer):
  813. (define *defmacros* '())
  814. (define (defmacro? m) (and (assq m *defmacros*) #t))
  815.  
  816. (define defmacro:transformer
  817.   (lambda (f)
  818.     (procedure->memoizing-macro
  819.       (lambda (exp env)
  820.     (copy-tree (apply f (cdr exp)))))))
  821.  
  822. (define defmacro
  823.   (let ((defmacro-transformer
  824.       (lambda (name parms . body)
  825.         (let ((transformer `(lambda ,parms ,@body)))
  826.           `(define ,name
  827.          (,(lambda (transformer)
  828.              (set! *defmacros* (acons name transformer *defmacros*))
  829.              (defmacro:transformer transformer))
  830.           ,transformer))))))
  831.     (set! *defmacros* (acons 'defmacro defmacro-transformer *defmacros*))
  832.     (defmacro:transformer defmacro-transformer)))
  833.  
  834. (define (macroexpand-1 e)
  835.   (if (pair? e) (let ((a (car e)))
  836.           (cond ((symbol? a) (set! a (assq a *defmacros*))
  837.                      (if a (apply (cdr a) (cdr e)) e))
  838.             (else e)))
  839.       e))
  840.  
  841. (define (macroexpand e)
  842.   (if (pair? e) (let ((a (car e)))
  843.           (cond ((symbol? a)
  844.              (set! a (assq a *defmacros*))
  845.              (if a (macroexpand (apply (cdr a) (cdr e))) e))
  846.             (else e)))
  847.       e))
  848.  
  849. (define gentemp
  850.   (let ((*gensym-counter* -1))
  851.     (lambda ()
  852.       (set! *gensym-counter* (+ *gensym-counter* 1))
  853.       (string->symbol
  854.        (string-append "scm:G" (number->string *gensym-counter*))))))
  855.  
  856. (define defmacro:eval slib:eval)
  857. (define defmacro:load load)
  858.  
  859. (define (slib:eval-load <filename> evl)
  860.   (if (not (file-exists? <filename>))
  861.       (set! <filename> (string-append <filename> (scheme-file-suffix))))
  862.   (call-with-input-file <filename>
  863.     (lambda (port)
  864.       (let ((old-load-pathname *load-pathname*))
  865.     (set! *load-pathname* <filename>)
  866.     (do ((o (read port) (read port)))
  867.         ((eof-object? o))
  868.       (evl o))
  869.     (set! *load-pathname* old-load-pathname)))))
  870.  
  871.  
  872. ;;; {Some Handy Macros}
  873. ;;;
  874.  
  875. ;;; Trace gets redefmacroed when tracef autoloads.
  876. (defmacro trace x
  877.   (if (null? x) '()
  878.       `(begin ,@(map (lambda (x) `(set! ,x (trace:tracef ,x ',x))) x))))
  879.  
  880. (defmacro defvar (var val)
  881.   `(if (not (defined? ,var)) (define ,var ,val)))
  882.  
  883.  
  884. ;;; {Transcendental Functions}
  885. ;;;
  886.  
  887. (cond ((and (inexact? (string->number "0.0")) (not (defined? exp)))
  888.        (if (defined? usr:lib)
  889.        (load (in-vicinity (library-vicinity) "Transcen")
  890.          (usr:lib "m"))
  891.        (load (in-vicinity (library-vicinity) "Transcen"
  892.                   (scheme-file-suffix))))
  893.        (set! abs magnitude)))
  894.  
  895.  
  896. ;;; {These are missing from the C code.}
  897. ;;;
  898.  
  899. (define (symbol-append . args)
  900.   (string->symbol (apply string-append args)))
  901.  
  902. (define (obarray-symbol-append ob . args)
  903.   (string->obarray-symbol (apply string-append args)))
  904.  
  905. (define make-kw make-keyword)
  906. (define (symbol->keyword symbol)
  907.   (make-keyword (symbol-append '- symbol)))
  908. (define (keyword->symbol kw)
  909.   (let ((sym (keyword-symbol kw)))
  910.     (string->symbol (substring sym 1 (length sym)))))
  911.  
  912. (define (kw-arg-ref args kw)
  913.   (let ((rem (member kw args)))
  914.     (and rem (pair? (cdr rem)) (cadr rem))))
  915.  
  916. (define (list-index l k)
  917.   (let loop ((n 0)
  918.          (l l))
  919.     (and (not (null? l))
  920.      (if (eq? (car l) k)
  921.          n
  922.          (loop (+ n 1) (cdr l))))))
  923.  
  924. (define (make-list n init)
  925.   (let loop ((answer '())
  926.          (n n))
  927.     (if (<= n 0)
  928.     answer
  929.     (loop (cons init (answer)) (- n 1)))))
  930.  
  931.  
  932.  
  933. ;;; {Arrays}
  934. ;;;
  935.  
  936. (if (defined? array?)
  937.     (begin
  938.       (define uniform-vector? array?)
  939.       (define make-uniform-vector dimensions->uniform-array)
  940. ;      (define uniform-vector-ref array-ref)
  941.       (define (uniform-vector-set! u i o)
  942.     (uniform-vector-set1! u o i))
  943.       (define uniform-vector-fill! array-fill!)
  944.       (define uniform-vector-read! uniform-array-read!)
  945.       (define uniform-vector-write uniform-array-write)
  946.  
  947.       (define (make-array fill . args)
  948.     (dimensions->uniform-array args () fill))
  949.       (define (make-uniform-array prot . args)
  950.     (dimensions->uniform-array args prot))
  951.       (define (list->array ndim lst)
  952.     (list->uniform-array ndim '() lst))
  953.       (define (list->uniform-vector prot lst)
  954.     (list->uniform-array 1 prot lst))
  955.       (define (array-shape a)
  956.     (map (lambda (ind) (if (number? ind) (list 0 (+ -1 ind)) ind))
  957.          (array-dimensions a)))))
  958.  
  959.  
  960. ;;; {Lvectors}
  961. ;;;
  962.  
  963. ;; These are the offsets of hook functions within a type lvector.
  964. ;; They must agree with declarations in scm.h (bleah)
  965. ;;
  966. (define lvector-hook-ref-fn 1)
  967. (define lvector-hook-set-fn 2)
  968. (define lvector-hook-print-fn 3)
  969. (define lvector-hook-equal-fn 4)
  970. (define lvector-hook-isa-fn 5)
  971.  
  972. (define lvector-hook-slots 6)
  973.  
  974.  
  975. ;; names that will go away eventually...
  976. ;;
  977. (define lvector_hook_ref_fn lvector-hook-ref-fn)
  978. (define lvector_hook_set_fn lvector-hook-set-fn)
  979. (define lvector_hook_print_fn lvector-hook-print-fn)
  980. (define lvector_hook_equal_fn lvector-hook-equal-fn)
  981. (define lvector_hook_isa_fn lvector-hook-isa-fn)
  982. (define lvector_hook_slots lvector-hook-slots)
  983.  
  984. ;;; {The Module System}
  985. ;;;
  986.  
  987. (load (in-vicinity (library-vicinity) "Gmodules.scm"))
  988.  
  989.  
  990. ;;; {Running Repls}
  991. ;;;
  992.  
  993.  
  994. ;; Mystery integer passed to error handlers:
  995. ;;
  996. (define repl-quit -1)
  997. (define repl-abort -2)
  998. (define on-a-new-stack #f)
  999.  
  1000. (define (verbose-repl verbosity prompt env)
  1001.   (let ((old-v (verbose)))
  1002.     (dynamic-wind
  1003.      (lambda () (set! old-v (verbose verbosity)))
  1004.      (lambda () (repl prompt env))
  1005.      (lambda () (set! verbosity (verbose old-v))))))
  1006.  
  1007. (define guile-prompt "guile> ")
  1008. (define (guile-repl-thunk)
  1009.   (verbose-repl (%default-verbosity) guile-prompt #f))
  1010.  
  1011. (define %%repl-thunk guile-repl-thunk)
  1012.  
  1013. (define rooted-repl
  1014.   (lambda (inp)
  1015.     (with-dynamic-root
  1016.      (lambda ()
  1017.        (let ((new-stack-req
  1018.           (call-with-current-continuation
  1019.            (lambda (cc)
  1020.          (set! on-a-new-stack
  1021.                (lambda (thunk)
  1022.              (call-with-current-continuation
  1023.               (lambda (cc2) (cc (cons thunk cc2))))))
  1024.          (with-input-from-port inp
  1025.            (lambda () (%%repl-thunk)))))))
  1026.      ((cdr new-stack-req) ((car new-stack-req)))))
  1027.      (lambda (errcode)
  1028.        (with-input-from-port inp
  1029.      (lambda ()
  1030.        (cond
  1031.         ((= errcode repl-quit) #t)
  1032.         (#t (%%repl-thunk)))))))))
  1033.  
  1034. (define stand-alone-repl
  1035.   (let ((stdin *stdin*))
  1036.     (lambda () (rooted-repl stdin))))
  1037.  
  1038.  
  1039. (define (synthetic-repl prompt read eval print port)
  1040.   (let ((repl (lambda ()
  1041.         (let loop ((form (begin (prompt) (read))))
  1042.           (print (eval form))
  1043.           (loop (begin (prompt) (read)))))))
  1044.     (with-dynamic-root
  1045.      (lambda () (with-input-from-port port repl))
  1046.      (lambda (errcode)
  1047.        (with-input-from-port port
  1048.      (lambda ()
  1049.        (cond
  1050.         ((= errcode repl-quit) #t)
  1051.         (#t (repl)))))))))
  1052.  
  1053.  
  1054.  
  1055. ;;; {Pleasant Wrappers for System Calls}
  1056. ;;;
  1057. ;; (load (in-vicinity (library-vicinity) "Gsystem.scm"))
  1058.  
  1059. ;;;  {Shorthand for small equal?-based Hash Tables}
  1060. ;;;
  1061.  
  1062. (define aref (hash-inquirer equal?))
  1063. (define aremove (hash-remover equal?))
  1064. (define aset! (hash-associator equal?))
  1065. (define (make-table) (make-hash-table 64))
  1066.  
  1067.  
  1068.  
  1069. ;;; {Parsing and Acting on the Command Line}
  1070. ;;;
  1071.  
  1072. ;;; Use *argv* instead of (program-arguments), to allow option
  1073. ;;; processing to be done on it.
  1074. (define *argv* (program-arguments))
  1075.  
  1076. ;;; This loads the user's initialization file, or files named in
  1077. ;;; program arguments.
  1078.  
  1079. (define (top-level-once thunk)
  1080.   (let ((didit #f))
  1081.     (catch #t
  1082.      (lambda ()
  1083.        (thunk)
  1084.        (if didit
  1085.        (error 'once-was-enough))
  1086.        (set! didit #t))
  1087.      (lambda err
  1088.        (if didit
  1089.        (error 'once-was-enough--error))
  1090.        (set! didit #t)
  1091.        (write (cons 'ERROR err) (current-error-port))
  1092.        (newline (current-error-port))
  1093.        #f))))
  1094.  
  1095.  
  1096. (define built-in-variable builtin-variable)
  1097.  
  1098. (top-level-once
  1099.  (lambda ()
  1100.    (or
  1101.     (eq? (software-type) 'THINKC)
  1102.     (member "-no-init-file" (program-arguments))
  1103.     (try-load
  1104.      (in-vicinity
  1105.       (let ((home (getenv "HOME")))
  1106.     (cond
  1107.      (home (case (software-type)
  1108.          ((UNIX COHERENT)
  1109.           (if (char=? #\/ (string-ref home (+ -1 (string-length home))))
  1110.               home            ;V7 unix has a / on HOME
  1111.               (string-append home "/")))
  1112.          (else home)))
  1113.  
  1114.      ((and (defined? getpw) (defined? geteuid) (getpw (geteuid)))
  1115.       (vector-ref (getpw (geteuid)) 5))
  1116.  
  1117.      ((defined? user-vicinity) (user-vicinity))
  1118.  
  1119.      (t "/")))
  1120.       "ScmInit.scm"))
  1121.     (errno 0))))
  1122.  
  1123. (if (not (defined? *R4RS-macro*))
  1124.     (define *R4RS-macro* #f))
  1125.  
  1126. (if (not (defined? *interactive*))
  1127.     (define *interactive* #f))
  1128.  
  1129. (if (not (defined? 'type))
  1130.     (define type #f))
  1131.  
  1132. (top-level-once
  1133.  (lambda ()
  1134.    (cond
  1135.     ((and (> (length *argv*) 1) (char=? #\- (string-ref (cadr *argv*) 0)))
  1136.      (load (in-vicinity (library-vicinity) "getopt"))
  1137. ;;; (else
  1138. ;;;  (define *optind* 1)
  1139. ;;;  (define getopt:opt #f)
  1140. ;;;  (define (getopt argc argv optstring) #f))
  1141.  
  1142.      (let* ((simple-opts "muqvbis")
  1143.         (arg-opts '("a kbytes" "no-init-file" "p number"
  1144.                    "r feature" "f filename" "l filename"
  1145.                    "c string" "e string"))
  1146.         (opts (apply string-append ":" simple-opts
  1147.              (map (lambda (o)
  1148.                 (string-append (string (string-ref o 0)) ":"))
  1149.                   arg-opts)))
  1150.         (argc (length *argv*))
  1151.         (didsomething #f)
  1152.         (moreopts #t))
  1153.  
  1154.        (define (do-thunk thunk)
  1155.      (if *interactive*
  1156.          (thunk)
  1157.          (let ((complete #f))
  1158.            (with-dynamic-root
  1159.         (lambda ()
  1160.           (thunk)
  1161.           (set! complete #t))
  1162.         (lambda status
  1163.           ;; The thunk tried to escape its continuation in
  1164.           ;; an unusual way.  Give up.
  1165.           (quit))))))
  1166.  
  1167.        (define (do-string-arg)
  1168.      (require 'string-port)
  1169.      (do-thunk
  1170.       (lambda ()
  1171.         (eval
  1172.          (call-with-input-string
  1173.           (string-append "(begin " *optarg* ")")
  1174.           read))))
  1175.      (set! didsomething #t))
  1176.  
  1177.        (define (do-load file)
  1178.      (do-thunk
  1179.       (lambda ()
  1180.         (cond (*R4RS-macro* (require 'macro) (macro:load file))
  1181.           (else (load file)))))
  1182.      (set! didsomething #t))
  1183.  
  1184.        (define (usage preopt opt postopt)
  1185.      (define cep (current-error-port))
  1186.      (define indent (make-string 6 #\ ))
  1187.      (define i 3)
  1188.      (if (char? opt) (set! opt (string opt)))
  1189.      (display (string-append preopt opt postopt) cep)
  1190.      (newline cep)
  1191.      (display (string-append "Usage: " (car (program-arguments))
  1192.                  " [-a kbytes] [-" simple-opts "]") cep)
  1193.      (for-each
  1194.       (lambda (o)
  1195.         (display (string-append " [-" o "]") cep)
  1196.         (set! i (+ 1 i))
  1197.         (cond ((zero? (modulo i 4)) (newline cep) (display indent cep))))
  1198.       (cdr arg-opts))
  1199.      (display " [-- | -s | -] [file] [args...]" cep) (newline cep)
  1200.      (exit #f))
  1201.  
  1202.        ;; -a int => ignore (handled by run_scm)
  1203.        ;; -c str => (eval str)
  1204.        ;; -e str => (eval str)
  1205.        ;; -f str => (load str)
  1206.        ;; -l str => (load str)
  1207.        ;; -r str => (require str)
  1208.        ;; -p int => (verbose int)
  1209.        ;; -m     => (set! *R4RS-macro* #t)
  1210.        ;; -u     => (set! *R4RS-macro* #f)
  1211.        ;; -v     => (verbose 3)
  1212.        ;; -q     => (verbose 0)
  1213.        ;; -i     => (set! *interactive* #t)
  1214.        ;; -b     => (set! *interactive* #f)
  1215.        ;; -s     => set argv, don't execute first one
  1216.        ;; -no-init-file => don't load init file
  1217.        ;; --     => last option
  1218.  
  1219.        (let loop ()
  1220.      (case (getopt argc *argv* opts)
  1221.        ((#\a)
  1222.         (cond ((> *optind* 3)
  1223.            (usage "scm: option `-" getopt:opt "' must be first"))
  1224.           ((or (not (exact? (string->number *optarg*)))
  1225.                (not (<= 1 (string->number *optarg*) 10000)))
  1226.            ;;    This size limit should match scm.c ^^
  1227.            (usage "scm: option `-" getopt:opt
  1228.               (string-append *optarg* "' unreasonable")))))
  1229.        ((#\e #\c) (do-string-arg))    ;sh-like
  1230.        ((#\f #\l);;(set-car! *argv* *optarg*)
  1231.         (do-load *optarg*))
  1232.        ((#\r) (do-thunk (lambda ()
  1233.                   (if (and (= 1 (string-length *optarg*))
  1234.                        (char-numeric? (string-ref *optarg* 0)))
  1235.                   (case (string-ref *optarg* 0)
  1236.                     ((#\2) (require 'rev3-procedures)
  1237.                        (require 'rev2-procedures))
  1238.                     ((#\3) (require 'rev3-procedures))
  1239.                     ((#\4) (require 'rev4-optional-procedures))
  1240.                     ((#\5) (require 'dynamic-wind)
  1241.                        (require 'values)
  1242.                        (require 'macro)
  1243.                        (set! *R4RS-macro* #t))
  1244.                     (else (require (string->symbol *optarg*))))
  1245.                   (require (string->symbol *optarg*))))))
  1246.        ((#\p) (verbose (string->number *optarg*)))
  1247.        ((#\q) (verbose 0))
  1248.        ((#\v) (verbose 3))
  1249.        ((#\i) (set! *interactive* #t)    ;sh-like
  1250.           (verbose (max 2 (verbose))))
  1251.        ((#\b) (set! *interactive* #f))
  1252.        ((#\s) (set! moreopts #f)    ;sh-like
  1253.           (set! didsomething #t)
  1254.           (set! *interactive* #t))
  1255.        ((#\m) (set! *R4RS-macro* #t))
  1256.        ((#\u) (set! *R4RS-macro* #f))
  1257.        ((#\n) (if (not (string=? "o-init-file" *optarg*))
  1258.               (usage "scm: unrecognized option `-n" *optarg* "'")))
  1259.        ((#\:) (usage "scm: option `-" getopt:opt "' requires an argument"))
  1260.        ((#\?) (usage "scm: unrecognized option `-" getopt:opt "'"))
  1261.        ((#f) (set! moreopts #f)    ;sh-like
  1262.          (cond ((and (< *optind* (length *argv*))
  1263.                  (string=? "-" (list-ref *argv* *optind*)))
  1264.             (set! *optind* (+ 1 *optind*)))))
  1265.        (else (usage "scm: unknown option `-" getopt:opt "'")))
  1266.  
  1267.      (cond ((and moreopts (< *optind* (length *argv*)))
  1268.         (loop))
  1269.            ((< *optind* (length *argv*)) ;No more opts
  1270.         (set! *argv* (list-tail *argv* *optind*))
  1271.         (set! *optind* 1)
  1272.         (cond ((not didsomething) (do-load (car *argv*))
  1273.                       (set! *optind* (+ 1 *optind*))))
  1274.         (cond ((and (> (verbose) 2)
  1275.                 (not (= (+ -1 *optind*) (length *argv*))))
  1276.                (display "scm: extra command arguments unused:"
  1277.                 (current-error-port))
  1278.                (for-each (lambda (x) (display (string-append " " x)
  1279.                               (current-error-port)))
  1280.                  (list-tail *argv* (+ -1 *optind*)))
  1281.                (newline (current-error-port)))))
  1282.            ((and (not didsomething) (= *optind* (length *argv*)))
  1283.         (set! *interactive* #t)))))
  1284.  
  1285.      (cond ((not *interactive*) (quit))
  1286.        (*R4RS-macro*
  1287.         (require 'repl)
  1288.         (require 'macro)
  1289.         (let* ((oquit quit))
  1290.           (set! quit (lambda () (repl:quit)))
  1291.           (set! exit quit)
  1292.           (repl:top-level macro:eval)
  1293.           (oquit))))
  1294.      ;;otherwise, fall into non-macro SCM repl.
  1295.      )
  1296.     (else
  1297.      (begin (errno 0)
  1298.         (for-each load (cdr (program-arguments))))))))
  1299.  
  1300.  
  1301.  
  1302.